<?php
/*
#生产验证码
#lsj 2010-1-10
*/
if(!defined('APP_HOME')) exit('Access Denied');
class lib_class_captcha
{

  public $oImage;
  public $aFonts;
  public $iWidth;
  public $iHeight;
  public $iNumChars;
  public $iNumLines;
  public $iSpacing;
  public $bCharShadow;
  public $sOwnerText;
  public $aCharSet;
  public $bCaseInsensitive;
  public $vBackgroundImages;
  public $iMinFontSize;
  public $iMaxFontSize;
  public $bUseColour;
  public $sFileType;
  public $sCode = '';

  /*
  #构造函数，初始化参数
  */
  public function __construct ($iWidth = 200, $iHeight = 50, $aFonts = array())
	{

	 if(empty($aFonts)){
	    $fontsPATH = dirname(__FILE__).'/fonts/';
		$aFonts = array(
			$fontsPATH . 'VeraBd.ttf',
			$fontsPATH . 'VeraIt.ttf',
			$fontsPATH . 'Vera.ttf',
		);
	 }

	 $this->aFonts = $aFonts;#字体，使用时会随机用一种字体
	 $this->SetNumChars(4);#验证码的字符数
	 $this->SetNumLines(70);#背景线条密度
	 $this->DisplayShadow(false);#是否显示阴影效果
	 $this->SetOwnerText('');#自定义文本内容
	 $this->SetCharSet('0-9');#验证码内容的范围，如a-z 0-9 A-Z
	 $this->CaseInsensitive(true);#是否区分大小写
	 $this->SetBackgroundImages('');#背景图片
	 $this->SetMinFontSize(16);#文字大小的最小值
	 $this->SetMaxFontSize(25);#文字大小的最大值
	 $this->UseColour(false);#是否用彩色线条
	 $this->SetFileType('jpeg');#图片的格式
	 $this->SetWidth($iWidth);#验证码图片的宽度
	 $this->SetHeight($iHeight);#验证码图片的宽度

     return true;
  }


  /*
  #设置验证码图片的宽度
  */
  public function SetWidth($iWidth)
  {
	 $this->iWidth = $iWidth;
	 if ($this->iWidth > 500) $this->iWidth = 500;
	 $this->CalculateSpacing();
  }

  /*
  #设置验证码图片的高度
  */
  public function SetHeight($iHeight)
  {
	 $this->iHeight = $iHeight;
	 if ($this->iHeight > 200) $this->iHeight = 200;
  }

  /*
  #设置验证码的字符数
  */
  public function SetNumChars($iNumChars)
  {
	 $this->iNumChars = $iNumChars;
	 $this->CalculateSpacing();
  }

  /*
  #设置背景线条密度
  */
  public function SetNumLines($iNumLines)
  {
	 $this->iNumLines = $iNumLines;
  }

  /*
  #设置是否显示阴影效果
  */
  public function DisplayShadow($bCharShadow)
  {
	 $this->bCharShadow = $bCharShadow;
  }

  /*
  #设置自定义文本内容
  */
  public function SetOwnerText($sOwnerText)
  {
	 $this->sOwnerText = $sOwnerText;
  }

  /*
  #设置验证码内容的范围，如a-z 0-9 A-Z
  */
  public function SetCharSet($vCharSet)
  {
	 if (is_array($vCharSet)) {
		$this->aCharSet = $vCharSet;
	 } else {
		if ($vCharSet != '') {
		   $aCharSet = explode(',', $vCharSet);
		   $this->aCharSet = array();
		   foreach ($aCharSet as $sCurrentItem) {
			  if (strlen($sCurrentItem) == 3) {
				 $aRange = explode('-', $sCurrentItem);
				 if (count($aRange) == 2 && $aRange[0] < $aRange[1]) {
					$aRange = range($aRange[0], $aRange[1]);
					$this->aCharSet = array_merge($this->aCharSet, $aRange);
				 }
			  } else {
				 $this->aCharSet[] = $sCurrentItem;
			  }
		   }
		}
	 }
  }

  /*
  #设置是否区分大小写
  */
  public function CaseInsensitive($bCaseInsensitive)
  {
	 $this->bCaseInsensitive = $bCaseInsensitive;
  }

  /*
  #设置背景图片
  */
  public function SetBackgroundImages($vBackgroundImages)
  {
	 $this->vBackgroundImages = $vBackgroundImages;
  }

  /*
  #设置文字大小的最小值
  */
  public function SetMinFontSize($iMinFontSize)
  {
	 $this->iMinFontSize = $iMinFontSize;
  }

  /*
  #设置文字大小的最大值
  */
  public function SetMaxFontSize($iMaxFontSize)
  {
	 $this->iMaxFontSize = $iMaxFontSize;
  }

  /*
  #设置是否用彩色线条
  */
  public function UseColour($bUseColour)
  {
	 $this->bUseColour = $bUseColour;
  }

  /*
  #设置图片的格式
  */
  public function SetFileType($sFileType)
  {
	 if (in_array($sFileType, array('gif', 'png', 'jpeg'))) {
		$this->sFileType = $sFileType;
	 } else {
		$this->sFileType = 'jpeg';
	 }
  }


  /*
  #获取验证码的内容
  */
  public function GetCode()
  {
        return $this->sCode;
  }

  /*
  #计算字符间的间隔距离
  */
  public function CalculateSpacing()
  {
	 $this->iSpacing = (int)($this->iWidth / $this->iNumChars);
  }

  /*
  #绘出一些杂乱的小细线
  */
  public function DrawLines()
  {
	 for ($i = 0; $i < $this->iNumLines; $i++) {
		if ($this->bUseColour) {
		   $iLineColour = imagecolorallocate($this->oImage, rand(100, 250), rand(100, 250), rand(100, 250));
		} else {
		   $iRandColour = rand(100, 250);
		   $iLineColour = imagecolorallocate($this->oImage, $iRandColour, $iRandColour, $iRandColour);
		}
		imageline($this->oImage, rand(0, $this->iWidth), rand(0, $this->iHeight), rand(0, $this->iWidth), rand(0, $this->iHeight), $iLineColour);
	 }
  }

  /*
  #绘出定义的文字
  */
  public function DrawOwnerText()
  {
	 $iBlack = imagecolorallocate($this->oImage, 0, 0, 0);
	 $iOwnerTextHeight = imagefontheight(2);
	 $iLineHeight = $this->iHeight - $iOwnerTextHeight - 4;
	 imageline($this->oImage, 0, $iLineHeight, $this->iWidth, $iLineHeight, $iBlack);
	 imagestring($this->oImage, 2, 3, $this->iHeight - $iOwnerTextHeight - 3, $this->sOwnerText, $iBlack);
	 $this->iHeight = $this->iHeight - $iOwnerTextHeight - 5;
  }

  /*
  #产生图片的内容
  */
  public function GenerateCode()
  {
	 $this->sCode = '';
	 for ($i = 0; $i < $this->iNumChars; $i++) {
		if (count($this->aCharSet) > 0) {
		   $this->sCode .= $this->aCharSet[array_rand($this->aCharSet)];
		} else {
		   $this->sCode .= chr(rand(65, 90));
		}
	 }
  }

  /*
  #绘出图片内容
  */
  public function DrawCharacters()
  {
	 for ($i = 0; $i < strlen($this->sCode); $i++) {
		$sCurrentFont = $this->aFonts[array_rand($this->aFonts)];
		if ($this->bUseColour) {
		   $iTextColour = imagecolorallocate($this->oImage, rand(0, 100), rand(0, 100), rand(0, 100));

		   if ($this->bCharShadow) {
			  $iShadowColour = imagecolorallocate($this->oImage, rand(0, 100), rand(0, 100), rand(0, 100));
		   }
		} else {
		   $iRandColour = rand(0, 100);
		   $iTextColour = imagecolorallocate($this->oImage, $iRandColour, $iRandColour, $iRandColour);

		   if ($this->bCharShadow) {
			  $iRandColour = rand(0, 100);
			  $iShadowColour = imagecolorallocate($this->oImage, $iRandColour, $iRandColour, $iRandColour);
		   }
		}

		$iFontSize = rand($this->iMinFontSize, $this->iMaxFontSize);
		$iAngle = rand(-30, 30);
		$aCharDetails = imageftbbox($iFontSize, $iAngle, $sCurrentFont, $this->sCode[$i], array());
		$iX = $this->iSpacing / 4 + $i * $this->iSpacing;
		$iCharHeight = $aCharDetails[2] - $aCharDetails[5];
		$iY = $this->iHeight / 2 + $iCharHeight / 4;

		imagefttext($this->oImage, $iFontSize, $iAngle, $iX, $iY, $iTextColour, $sCurrentFont, $this->sCode[$i], array());

		if ($this->bCharShadow) {
		   $iOffsetAngle = rand(-30, 30);
		   $iRandOffsetX = rand(-5, 5);
		   $iRandOffsetY = rand(-5, 5);

		   imagefttext($this->oImage, $iFontSize, $iOffsetAngle, $iX + $iRandOffsetX, $iY + $iRandOffsetY, $iShadowColour, $sCurrentFont, $this->sCode[$i], array());
		}
	 }
  }


  /*
  #保存为图片文件
  #$sFilename： 图片所要保存的文件名，可为空，为空时输出到浏览器
  */
  public function WriteFile($sFilename)
  {
	 if ($sFilename == '') {
		header("Content-type: image/$this->sFileType");
	 }

	 switch ($this->sFileType) {
		case 'gif':
		   $sFilename != '' ? imagegif($this->oImage, $sFilename) : imagegif($this->oImage);
		   break;
		case 'png':
		   $sFilename != '' ? imagepng($this->oImage, $sFilename) : imagepng($this->oImage);
		   break;
		default:
		   $sFilename != '' ? imagejpeg($this->oImage, $sFilename) : imagejpeg($this->oImage);
	 }
  }

  /*
  #生产验证码图片
  #$sFilename： 图片所要保存的文件名，可为空
  */
  public function Create($sFilename = '')
  {
	 if (!function_exists('imagecreate') || !function_exists("image$this->sFileType")
     || ($this->vBackgroundImages != '' && !function_exists('imagecreatetruecolor'))){
		return false;
	 }

	 if (is_array($this->vBackgroundImages) || $this->vBackgroundImages != '') {
		$this->oImage = imagecreatetruecolor($this->iWidth, $this->iHeight);
		if (is_array($this->vBackgroundImages)) {
		   $iRandImage = array_rand($this->vBackgroundImages);
		   $oBackgroundImage = imagecreatefromjpeg($this->vBackgroundImages[$iRandImage]);
		} else {
		   $oBackgroundImage = imagecreatefromjpeg($this->vBackgroundImages);
		}
		imagecopy($this->oImage, $oBackgroundImage, 0, 0, 0, 0, $this->iWidth, $this->iHeight);
		imagedestroy($oBackgroundImage);
	 } else {
		$this->oImage = imagecreate($this->iWidth, $this->iHeight);
	 }

	 imagecolorallocate($this->oImage, 255, 255, 255);

	 if ($this->sOwnerText != '') {
		$this->DrawOwnerText();
	 }

	 if (!is_array($this->vBackgroundImages) && $this->vBackgroundImages == '') {
		$this->DrawLines();
	 }

	 $this->GenerateCode();
	 $this->DrawCharacters();
	 $this->WriteFile($sFilename);
	 imagedestroy($this->oImage);

	 return $this->sCode;
  }






}

/*
for example:

$captcha->SetNumChars(4);//设置显示字符数
$captcha->SetWidth($width);//图片宽度
$captcha->SetHeight($height);//图片高度
$captcha->UseColour(true); //彩色线条
$captcha->SetOwnerText('hello world');//文字
$captcha->SetCharSet('0-9a-zA-Z');//字符的内容范围
$captcha->DisplayShadow(true); //字符阴影
$captcha->SetBackgroundImages(WEB_ROOT.'images/button_bg.jpg');//背景图片
$captcha->SetNumLines(30);//设置背景线条密度,默认70
$captcha->SetMinFontSize(14);//最低字符大小
$captcha->SetMaxFontSize(16);//最高字符大小
$captcha->SetFileType('jpeg');//创建图片的格式
$captcha->Create();//生产

*/




?>
